package com.miao.im.service.auth;

import com.miao.im.common.Constant;
import com.miao.im.dto.AuthRequestDto;
import com.miao.im.model.AuthResponseModel;
import com.miao.im.repository.IUserRepository;
import com.miao.im.scheduler.WsScheduler;
import com.miao.im.server.session.SessionContext;
import com.miao.im.server.session.SessionManager;
import com.miao.im.support.exception.AuthenticationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * @Auther: miaoguoxin
 * @Date: 2021/3/5 11:14
 * @Description:
 */
@Service
@Slf4j
public class SocketAuthManager implements IAuthManager<AuthResponseModel.AuthResponse> {
    @Autowired
    private IUserRepository userRepository;
    @Autowired
    private WsScheduler wsScheduler;

    @Override
    public AuthResponseModel.AuthResponse register(AuthRequestDto dto) {
        return null;
    }

    @Override
    public AuthResponseModel.AuthResponse login(AuthRequestDto dto) {

        return null;
    }

    @Override
    public Mono<AuthResponseModel.AuthResponse> reactiveLogin(AuthRequestDto dto) {
        return userRepository.reactiveGetBySessionId(dto.getUsername())
                .switchIfEmpty(Mono.error(new AuthenticationException("用户不存在")))
                .flatMap(userDo -> {
                    AuthResponseModel.AuthResponse authResponse = AuthResponseModel.AuthResponse.newBuilder()
                            .setUserId(String.valueOf(userDo.getId()))
                            .setUsername(userDo.getUsername())
                            .setNickname(userDo.getNickname())
                            .setAvatar(userDo.getAvatar())
                            .setRoutingKey(Constant.DISPATCHER_ROUTING_KEY_NAME)
                            .setDeviceNumber(dto.getDeviceNumber())
                            .setTime(System.currentTimeMillis())
                            .build();
                    return Mono.just(authResponse);
                })
                .doOnSuccess(authResponse -> userRepository.reactiveSaveOnlineUser(authResponse).subscribe());
    }

    @Override
    public void logout(String userId, String deviceNumber) {
        userRepository.delOnlineUser(userId, deviceNumber);
        wsScheduler.removeWaitingUser(userId, deviceNumber);
    }


    @Override
    public void allOut() {
        List<SessionContext> sessionContexts = SessionManager.getAll();
        for (SessionContext context : sessionContexts) {
            if (!context.isAuth()) {
                continue;
            }
            userRepository.delOnlineUser(context.getUserInfo().getUserId(), context.getUserInfo().getDeviceNumber());
        }
    }

    @Override
    public void refreshLoginTime(String userId, String deviceNumber) {
       // userRepository.refreshOnlineUser(userId, deviceNumber);
    }
}
